# DatabaseV3.py - Performs read/write operations on a file containing event entries.
__author__ = "Lewis Marhin"

#import unittest
class File:
	# Param: None
	# Notes:
	#	Will initialize file extension, field delimiter and entry delimiter.
	# Return: self (implicit)
	def __init__(self):
		# tsv (tab seperated values) files can be opened by spreadsheet processors
		# just like csv files.
		self.fileExt = ".tsv"
		self.fieldDelim = "\t"
		self.entryDelim = "\n"
	
	# Param: string day, dict entry
	# 	string day: A day of the week all lower case. It will be the name of the file that is created.
	# 	dict entry: Must contain these keys: ID,subject,type,from,until,location,weekly (in any order)
	# Notes:
	#	Will write to format: ID \t subject \t type \t Location \t from \t until \t location \t weekly\n
	# 	Will create a file.
	# Return: None
	def add(self, day, entry):
		txtFile = open(day + self.fileExt, "a")
			
		txtFile.write(entry["ID"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["subject"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["type"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["from"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["until"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["location"])
		txtFile.write(self.fieldDelim)
		txtFile.write(entry["weekly"])
		
		txtFile.write(self.entryDelim)
		txtFile.close()
	
	# Param: string fileN
	# 	string fileN: Name of the file. Should be a day of the week, all lower case.
	# Notes:
	#	Retrieves all entries from sepcified file.
	# Return: list(dict*): (*) indicates varying number of said variable. Will be a list of events.
	def get(self, fileN):
		entries = list(dict())
		txtFile = open(fileN + self.fileExt, "r")
		
		for line in txtFile:
			line = line.rsplit('\t')

			entries.append({"ID":line[0], "subject":line[1], "type":line[2], "from":line[3], "until":line[4], "location":line[5], "weekly":line[6]})
		txtFile.close()
		
		return entries

	# Param: string theID, string theString
	# 	string theID: The ID number to be checked.
	# 	string theString: Then entry to check.
	# Notes:
	#	Comapares an ID value and an entry's ID value.
	# Return: boolean: True for a match, False for no match.
	def checkID(theID, theString):
		tmpID = ""
		index = 0
		
		for letters in theString:
			if theString[index] == "\t":
				break
			else:
				tmpID += theString[index]
			index += 1

		if tmpID == theID:
			return True
		else:
			return False

	# Param: string theID, string theEvent
	#	string theID: The ID number of the event to edit.
	#	string theEvent: The event to modify.
	# Notes:
	#	An abstraction function. Simply hides the fact that an edit is an erasure and then an addition.
	# Return: None
	def edit(theID, theEvent):
		erase(theID)
		add(theEvent)

	# Param: string theID, string fileN
	#	string theID: Is the ID number of the event which is to be erased.
	#	string fileN: Is the name of the file to check for ID for. Should be a day of the week, all lower case and no extension.
	# Notes:
	#	Erases an entry from the file with a specific ID.
	#	May seem inefficient but reduces memory overhead and the chance of file corruption.
	# Return: None
	def erase(theID, fileN):
		tmp = ""
		txtFile = open(fileN + self.fileExt, "r")
		tmpFile = open("bkup_" + fileN + self.fileExt, 'w')
		
		for line in txtFile:
			if checkID(theID, line) == False:
				tmpFile.write(line)
		tmpFile.close()
		txtFile.close()
		txtFile = open(fileN, "w")
		tmpFile = open("bkup_" + fileN + self.fileExt, 'r')
		txtFile.write(tmpFile.read())
		tmpFile.close()
		txtFile.close()

	# Param: string fileN
	#	string fileN: The name of the file to be erases. Should be day of the week, all lower case, no file extensions.
	# Notes:
	#	Intended for testing purposes but may be used later.
	#	Erases the contents of SPECIFIED file.
	# Return: None
	def eraseAll(self, fileN):
		txtFile = open(fileN + self.fileExt, "w")
		txtFile.close()

	# OLD TEST CASES
	"""class Tester(unittest.TestCase):
		# Tests to check if ID checking works.
		def testCheckIDTrue(self):
			self.assert_(True == checkID("568", "568\tTutorial\t564\t"))

		def testCheckIDFalse(self):
			self.assert_(False == checkID("551", "568\tTutorial\t564\t"))

		# Tests file write without preformatted text.
		def testReadWrite1(self):
			add("30", "Lecture", "12:00", "12:50", "XK2455", "Bob", "Z3.343", "Repeat:Weekly")
			add("31", "Tutorial", "1:00", "1:50", "XK3578", "Bob", "Z3.343", "Repeat:Weekly")
			add("32", "Lecture", "2:00", "2:50", "XK2311", "Bob", "Z3.343", "Repeat:Weekly")
			add("33", "Practical", "3:00", "3:50", "ZR4314", "Bob", "Z3.343", "Repeat:Weekly")
			self.assert_(get("32") == "32" + self.fieldDelim + "Lecture" + self.fieldDelim + "2:00" + self.fieldDelim + "2:50" + self.fieldDelim + "XK2311" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly" + self.fieldDelim + "\n")
			eraseAll()

		# Tests read failure.
		def testReadFailure(self):
			add("30", "Lecture", "12:00", "12:50", "XK2455", "Bob", "Z3.343", "Repeat:Weekly")
			add("31", "Tutorial", "1:00", "1:50", "XK3578", "Bob", "Z3.343", "Repeat:Weekly")
			add("32", "Lecture", "2:00", "2:50", "XK2311", "Bob", "Z3.343", "Repeat:Weekly")
			add("33", "Practical", "3:00", "3:50", "ZR4314", "Bob", "Z3.343", "Repeat:Weekly")
			self.assert_(get("34") == "")
			eraseAll()

		# Tests file write with preformatted text.
		def testReadWrite2(self):
			txt = "30" + self.fieldDelim + "Lecture" + self.fieldDelim + "12:00" + self.fieldDelim + "12:50" + self.fieldDelim + "XK2455" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			txt2 = "31" + self.fieldDelim + "Tutorial" + self.fieldDelim + "1:00" + self.fieldDelim + "1:50" + self.fieldDelim + "XK3578" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			txt3 = "32" + self.fieldDelim + "Lecture" + self.fieldDelim + "2:00" + self.fieldDelim + "2:50" + self.fieldDelim + "XK2311" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			txt4 = "33" + self.fieldDelim + "Practical" + self.fieldDelim + "3:00" + self.fieldDelim + "3:50" + self.fieldDelim + "ZR4314" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			add(txt)
			add(txt2)
			add(txt3)
			add(txt4)
			self.assert_(get("31") == txt2 + "\t\n")
			eraseAll()

		# Test if editting is working correctly
		def testEdit(self):
			txt = "30" + self.fieldDelim + "Lecture" + self.fieldDelim + "12:00" + self.fieldDelim + "12:50" + self.fieldDelim + "XK2455" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			txt2 = "30" + self.fieldDelim + "Practical" + self.fieldDelim + "12:00" + self.fieldDelim + "12:50" + self.fieldDelim + "XK2455" + self.fieldDelim + "Bob" + self.fieldDelim + "Z3.343" + self.fieldDelim + "Repeat:Weekly"
			add(txt)
			edit("30", txt2)
			self.assert_(get("30") == txt2 + "\t\n")

	if __name__ == "__main__":
		unittest.main()"""
